package me.lubinn.Vicincantatio.Spells;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import net.minecraft.server.EntityFireball;
import net.minecraft.server.EntityLiving;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.util.Vector;

public class DurationSpell extends Spell 
{
	protected Timer timer = new Timer();
	
	protected int delay = 0;
	protected int period = 100;
	
	TimerTask task = new TimerTask()
	{
		public void run()
		{
			//code goes here;
		}
	};

	public Spell CastSpell(PlayerChatEvent event, Material mat, int size,
			Map<String, Boolean> augments) 
	{
		timer.scheduleAtFixedRate(task, delay, period);
		return this;
	}
}

class Hover extends DurationSpell
{	
	public Spell CastSpell(final PlayerChatEvent event, Material mat, final int size, Map<String, Boolean> augments)
	{
		
		delay = 0; //milliseconds
		period = 200; //milliseconds
		//Timer hoverTimer = new Timer();
    	
		//Timing thinger
		task = new TimerTask()
     	{
			int iterations = 0;
			public void run() 
    	    {
    	    	Vector initialVelocity = event.getPlayer().getVelocity();
    	    	Vector hover = initialVelocity.clone().setY(.2);
    	    	event.getPlayer().setVelocity(hover);
    	    	
    	    	//Gracefully land without damage
    	    	event.getPlayer().setFallDistance(0);
    	    	event.getPlayer().setRemainingAir(0);
      	  
    	    	//HOW DO I STOP THIS CRAZY THING
        	    iterations++;
        	    if (iterations >= (25 + (int)(size*3.5)))
        	    	this.cancel();
    	    }
         };	
	
        //do it once on cast, then each subsequent 200 ms for 35 iterations = 35*.2 seconds = 7 seconds
        timer.scheduleAtFixedRate(task, delay, period);
	
	
	    return this;
	}
}

class ChasmaTempestas extends DurationSpell
{
	public Spell CastSpell(final PlayerChatEvent event, Material mat, final int size, Map<String, Boolean> augments)
	{
		final boolean force = augments.containsKey("force");
		final boolean book = augments.containsKey("book");
		
        //OK, 5 seconds duration of this, 1 second between storm 
        
        delay = 0; //milliseconds
        period = 1000; //milliseconds
        
        //Timing thinger
        TimerTask task = new TimerTask()
        {
            int iterations = 0;
            public void run() 
            {
                CraftWorld world = (CraftWorld)event.getPlayer().getWorld();
        
                CraftPlayer craftPlayer = (CraftPlayer) event.getPlayer();
                EntityLiving playerEntity = craftPlayer.getHandle();            
                
                for (int i = 0; i < (int)(2.0*size*size) + 1; i++)
                {
                        //FIXME: KEEPS UPDATING BLOCK, can channel it and look around and it follows you, i want it to stay at that orig. spot
                        Location location = event.getPlayer().getTargetBlock(null, 500).getLocation();
                        Vector aim = event.getPlayer().getEyeLocation().getDirection().normalize();
                                
                        Location location1 = location.clone();
                        
                        location1.setX(location.getX());
                        location1.setY(120);
                        location1.setZ(location.getZ());
                        
                        Vector r = Vector.getRandom().subtract(new Vector(0.5, 0.5, 0.5)).normalize().multiply(2+size);
                        Vector v = location1.toVector().add(r);
                        
                        //For the augment
                        Vector v1 = location.toVector().add(r.multiply(size/2));
                
                
                        EntityFireball fireball = new EntityFireball(((CraftWorld) craftPlayer.getWorld()).getHandle(), playerEntity,0,-1,0);
                
                        //fireball.setDirection(aim.getX(), aim.getY(), aim.getZ());
                
                        fireball.locX = v.getX();
                        fireball.locY = v.getY();
                        fireball.locZ = v.getZ();
                        
                        if(force && book)
                        {
                        	world.strikeLightning(v1.toLocation(world));
                        }
                
//                      fireball.motX = aim.getX() * .1;
//                      fireball.motY = aim.getY() * .1;
//                      fireball.motZ = aim.getZ() * .1;
                
                        ((CraftWorld) craftPlayer.getWorld()).getHandle().addEntity(fireball);
                                
                }
             //HOW DO I STOP THIS CRAZY THING
	             iterations++;
	             if (iterations >= 6)
	                     this.cancel();
            }
        };
        
        //do it once on cast, then each subsequent 1 seconds for 6 seconds
        timer.scheduleAtFixedRate(task, delay, period);           
	    return this;
	}
}

class Root extends DurationSpell
{	
	public Spell CastSpell(final PlayerChatEvent event, Material mat, final int size, Map<String, Boolean> augments)
	{
		//This roots the target player by making velocity = 0 every .1 seconds for size seconds
		delay = 0;
		period = 100;
		
		task = new TimerTask()
		{
			int iterations = 0;
			public void run()
			{
				Location location = event.getPlayer().getTargetBlock(null, 500).getLocation();
				World world = event.getPlayer().getWorld();
				List<Entity> entities = world.getEntities();
				for(Iterator<Entity> iterator = entities.iterator(); iterator.hasNext();)
				{
					Entity entity = iterator.next();
					Location oloc = entity.getLocation();
					//			Distance clause					is player						not self
		         	if(location.distance(oloc) <= 5D && ((entity instanceof Player)) && entity != event.getPlayer())
		         		((CraftPlayer) entity).setVelocity(new Vector(0,0,0));
		         	
		         	//HOW DO I STOP THIS CRAZY THING
		            iterations++;
		            if (iterations >= (int)(period*size*10))
		            	this.cancel();
		      	}
			}
		};
	
		//spell code goes here
		timer.scheduleAtFixedRate(task, delay, period);     
	    return this;
	}
}


//TEMPLATE FOR DURATIONSPELLS
//
//class Foo extends DurationSpell
//{
//	int foo;
//	int bar;
//	int foobar;
//	
//	Foo()
//	{
//		task = new TimerTask()
//		{
//			public void run()
//			{
//				return;
//			}
//		};
//		delay = 14;
//		period = 314;
//	}
//}
